// services/persons.js
import axios from "axios";
const baseURL = "http://localhost:3001/persons"

const getPersons = async () => {
  const request = axios.get(baseURL)
  const response = await request;
  return response.data;
}

const postPerson = async (person) => {
  const request = axios.post(baseURL, person)
  const response = await request;
  return response.data;
}

const deletePerson = async (id) => {
  const request = axios.delete(`${baseURL}/${id}`)
  const response = await request;
  return response.data;
}

const putPerson = async (newPhonebook,id) => {
  const request = axios.put(`${baseURL}/${id}`, newPhonebook)
  const response = await request;
  return response.data;
}

export default {
  getPersons,
  postPerson,
  deletePerson,
  putPerson
}

// App.js
import React, { useState, useEffect } from 'react'
import personService from './services/persons'

const Notification = ({ notify }) => {
  if (notify === null) {
    return null
  }
  const { message, className } = notify
  return (
    <div className={className}>
      {message}
    </div>
  )
}

const Filter = ({ filter, handleFilterChange }) => {
  return (
    <form>
      <div>
        filter shown with<input value={filter} onChange={handleFilterChange}></input>
      </div>
    </form>
  )
}

const PersonForm = ({ persons, setPersons, setMessage }) => {

  const [newName, setNewName] = useState('')
  const [newNumber, setNewNumber] = useState('')

  const handleNameChange = (event) => setNewName(event.target.value)
  const handleNumberChange = (event) => setNewNumber(event.target.value)


  const addPerson = (event) => {
    event.preventDefault()
    const existingPerson = persons.find((person) => person.name === newName)
    const personObject = {
      name: newName,
      number: newNumber,
    }
    if (existingPerson !== undefined) {
      if (window.confirm(`${newName} already in phonebook, replace the old number with a new one?`)) {
        personService
          .putPerson(personObject, existingPerson.id)
          .then((returnPerson) => {
            setPersons(persons.map(person => person.id === returnPerson.id ? returnPerson : person))
            setMessage({ message: `Updated ${returnPerson.name}`, className: 'success' })
            setTimeout(() => {
              setMessage(null)
            }, 5000)
          })
      }
    }
    else {
      personService
        .postPerson(personObject)
        .then((returnPerson) => {
          setPersons(persons.concat(returnPerson))
          setMessage({ message: `Added ${returnPerson.name}`, className: 'success' })
          setTimeout(() => {
            setMessage(null)
          }, 5000)
        })
        .catch((error) => {
          setMessage({ message: error.response.data, className: 'error' })
          setTimeout(() => {
            setMessage(null)
          }, 5000)
        })
    }
    setNewName('')
    setNewNumber('')
  }

  return (
    <form onSubmit={addPerson}>
      <div>
        name: <input value={newName} onChange={handleNameChange} />
      </div>
      <div>number: <input value={newNumber} onChange={handleNumberChange} /></div>
      <div>
        <button type="submit">add</button>
      </div>
    </form>
  )
}

const Persons = ({ persons, handleDelete }) => {
  return persons.map((person) => <p key={person.id}>{person.name} {person.number}<button onClick={() => handleDelete(person.id, person.name)}>delete</button></p>)
}

const App = () => {
  const [persons, setPersons] = useState([])
  const [filter, setFilter] = useState('')
  const [filterPersons, setFilterPersons] = useState(persons)
  const [message, setMessage] = useState(null)

  const handleFilterChange = (event) => {
    setFilter(event.target.value)
    setFilterPersons(persons.filter((person) => (person.name.toLowerCase().indexOf(event.target.value.toLowerCase()) !== -1)))
  }

  const handleDelete = (id, name) => {
    if (window.confirm(`Delete ${name}`)) {
      personService
        .deletePerson(id)
        .then(() => {
          personService
            .getPersons()
            .then((returnPersons) => {
              setPersons(returnPersons)
            })
        })
        .catch(error => {
          setMessage({ message: `Information of ${name} has already been removed from server`, className: 'error' })
          setTimeout(() => {
            setMessage(null)
          }, 5000)
        })
    }
  }

  useEffect(() => {
    personService
      .getPersons()
      .then((returnPersons) => {
        setPersons(returnPersons)
      })
  }, [])

  return (
    <div>
      <h2>Phonebook</h2>
      <Filter filter={filter} handleFilterChange={handleFilterChange}></Filter>
      <Notification notify={message} />
      <h2>add a new</h2>
      <PersonForm persons={persons} setPersons={setPersons} setMessage={setMessage}></PersonForm>
      <h2>Numbers</h2>
      {filter === '' ?
        <Persons persons={persons} handleDelete={handleDelete}></Persons> :
        <Persons persons={filterPersons} handleDelete={handleDelete}></Persons>
      }
    </div>
  )
}

export default App

// index.js
import ReactDOM from 'react-dom';
import App from './App';
import './index.css';

ReactDOM.render(<App />,document.getElementById('root'));

// index.css
.success {
	border: 6px solid green;
	background: lightgray;
	color: green;
	font-size: 26px;
	padding: 20px;
	margin: 30px;
}

.error {
	border: 6px solid red;
	background: lightgray;
	color: red;
	font-size: 26px;
	padding: 20px;
	margin: 30px;
}